﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Security.AccessControl;

namespace FindDuplicateFile
{
    /// <summary>
    /// Noeud de type Dossier
    /// </summary>
    public class FSDirectoryNode : FSNode
    {
        private FSDirectoryNode(FSDirectoryNode parent, DirectoryInfo dinfo)
        {
            Parent = parent;
            Name = dinfo.Name;
            Path = dinfo.FullName;
            Size = 0;
            CreationTime = dinfo.CreationTime;
            LastAccessTime = dinfo.LastAccessTime;
            LastWriteTime = dinfo.LastWriteTime;

            FilesCount = 0;
            Directories = new List<FSDirectoryNode>();
            Files = new List<FSFileNode>();
        }

        public static FSDirectoryNode CreateFSDirectoryNode(FSDirectoryNode parent, DirectoryInfo dinfo, string sFileSearchPattern, IWorkInProgress wip )
        {
            FSDirectoryNode Node = new FSDirectoryNode(parent,dinfo);
            
            // Liste des fichiers du directory courant
            try
            {
                FileInfo[] aFileInfo = dinfo.GetFiles(sFileSearchPattern);
                foreach (FileInfo fi in aFileInfo)
                {
                    FSFileNode file = new FSFileNode(fi);
                    Node.Files.Add(file);
                    Node.LocalFilesSize += file.Size;
                    Node.FilesSize += file.Size;
                    Node.LocalFilesCount++;
                    Node.FilesCount++;
                }
            }
            catch (System.UnauthorizedAccessException)
            {
            }

            // List des dossiers du repertoire courant
            try
            {
                DirectoryInfo[] aDirInfo = dinfo.GetDirectories();
                foreach (DirectoryInfo diSubDir in aDirInfo)
                {
                    if ((diSubDir.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
                    {
                        if (wip != null)
                            wip.AdvanceWork(Node.Path);

                        FSDirectoryNode subNode = CreateFSDirectoryNode(Node, diSubDir, sFileSearchPattern,wip);
                        Node.Directories.Add(subNode);
                        Node.FilesCount += subNode.FilesCount;
                        Node.FilesSize += subNode.FilesSize;
                        Node.LocalDirectoriesCount++;
                        Node.DirectoriesCount += subNode.LocalDirectoriesCount;
                    }
                }
            }
            catch (System.UnauthorizedAccessException)
            {
            }

            Node.DirectoriesCount += Node.LocalDirectoriesCount;

            return Node;
        }

        public override void OpenDirectory()
        {
            ProcessStartInfo fileFolder = new ProcessStartInfo("explorer.exe", String.Format("/e,\"{0}\"", Path));
            fileFolder.UseShellExecute = false;
            Process.Start(fileFolder);
        }

        public override void OpenFile()
        {
            // NOTHING TO DO
        }

        public override void Delete()
        {
            Directory.Delete(Path);
        }

        public override string ToString()
        {
            return string.Format("{0},{1},{2}",Name,Directories.Count.ToString(),Files.Count.ToString());
        }

        static public void ExportExcel(List<FSDirectoryNode> lstDirectories)
        {
            // $$$ TODO
        }

        #region --------------- Property --------------------------
        public long FilesCount { get { return m_FilesCount; } set { if (value != m_FilesCount) { m_FilesCount = value; NotifyPropertyChanged("FilesCount"); } } }
        private long m_FilesCount;
        public long LocalFilesCount { get { return m_LocalFilesCount; } set { if (value != m_LocalFilesCount) { m_LocalFilesCount = value; NotifyPropertyChanged("LocalFilesCount"); } } }
        private long m_LocalFilesCount;
        public long DirectoriesCount { get { return m_DirectoriesCount; } set { if (value != m_DirectoriesCount) { m_DirectoriesCount = value; NotifyPropertyChanged("DirectoriesCount"); } } }
        private long m_DirectoriesCount;
        public long LocalDirectoriesCount { get { return m_LocalDirectoriesCount; } set { if (value != m_LocalDirectoriesCount) { m_LocalDirectoriesCount = value; NotifyPropertyChanged("LocalDirectoriesCount"); } } }
        private long m_LocalDirectoriesCount;

        public string BeautifulFilesSize { get { return ToBeautifulSize(m_FilesSize); } }
        public long FilesSize { get { return m_FilesSize; } set { if (value != m_FilesSize) { m_FilesSize = value; NotifyPropertyChanged("FilesSize"); } } }
        private long m_FilesSize;
        public string BeautifulLocalFilesSize { get { return ToBeautifulSize(m_LocalFilesSize); } }
        public long LocalFilesSize { get { return m_LocalFilesSize; } set { if (value != m_LocalFilesSize) { m_LocalFilesSize = value; NotifyPropertyChanged("LocalFilesSize"); } } }
        private long m_LocalFilesSize;
        
        public List<FSDirectoryNode> Directories { get { return m_Directories; } set { if (value != m_Directories) { m_Directories = value; NotifyPropertyChanged("Directories"); } } }
        private List<FSDirectoryNode> m_Directories;
        public List<FSFileNode> Files { get { return m_Files; } set { if (value != m_Files) { m_Files = value; NotifyPropertyChanged("Files"); } } }
        private List<FSFileNode> m_Files;
        public FSDirectoryNode Parent { get { return m_Parent; } set { if (value != m_Parent) { m_Parent = value; NotifyPropertyChanged("Parent"); } } }
        private FSDirectoryNode m_Parent;
        #endregion --------------- Property --------------------------
    }
}
